package com.freemypay.test.并发.终结任务.中断;

import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

/**
 * 中断演示  抛InterruptedException的可以被中断
 * @author yesixian
 * @date 2018年6月15日
 */
public class Interrupting {
	private static ExecutorService exec = Executors.newCachedThreadPool();
	
	static void test(Runnable r) throws InterruptedException {
		Future<?> f = exec.submit(r);
		TimeUnit.MILLISECONDS.sleep(100);
		System.out.println("Interrupting " + r.getClass().getName());
		f.cancel(true); // Interrupts if running
		System.out.println("Interrupt sent to " + r.getClass().getName());
	}
	
	public static void main(String[] args) throws InterruptedException {
		test(new SleepBlocked());
		test(new IOBlocked(System.in));
		test(new SynchronizedBlocked());
		TimeUnit.MILLISECONDS.sleep(3);
		System.out.println("Aborting with System.exit(0)");
		System.exit(0); // ... since last 2 interrupts failed
	}
}

/**
 * 可被中断
 * @author yesixian
 * @date 2018年6月15日
 */
class SleepBlocked implements Runnable {

	@Override
	public void run() {
		try {
			TimeUnit.MILLISECONDS.sleep(150);
		} catch (InterruptedException e) {
			System.out.println("InterruptedException");
		}
		System.out.println("Exiting SleepBlocked.run()");
	}
}

class IOBlocked implements Runnable {
	private InputStream in;
	
	public IOBlocked(InputStream is) {
		in = is;
	}

	@Override
	public void run() {
		System.out.println("Waiting for read();");
		try {
			in.read();
		} catch (IOException e) {
			if(Thread.currentThread().isInterrupted()) {
				System.out.println("Interrupted from blocked I/O");
			} else {
				throw new RuntimeException(e);
			}
		}
		System.out.println("Exiting IOBlocked.run()");
	}
}

/**
 * 该阻塞状态下不可被中断
 * @author yesixian
 * @date 2018年6月15日
 */
class SynchronizedBlocked implements Runnable {
	public synchronized void f() {
		while(true) { //Never releases lock
			Thread.yield();
		}
	}
	
	public SynchronizedBlocked() {
		// 创建线程获得f()的锁
		new Thread() {
			public void run() {
				f();
			};
		}.start();
	}
	
	@Override
	public void run() {
		System.out.println("Trying to call f()");
		// 一直阻塞
		f();
		System.out.println("Exiting SynchronizedBlocked.run()");
	}
}
